﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;


namespace Utilities
{
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct INTERFACEINFO
    {
        [MarshalAs(UnmanagedType.IUnknown)]
        public object punk;
        public Guid iid;
        public ushort wMethod;
    }

    [ComImport, ComConversionLoss, InterfaceType((short)1),
    Guid("00000016-0000-0000-C000-000000000046")]
    public interface IMessageFilter
    {
        [PreserveSig, MethodImpl(MethodImplOptions.InternalCall,
            MethodCodeType = MethodCodeType.Runtime)]
        int HandleInComingCall([In] uint dwCallType, [In] IntPtr htaskCaller,
            [In] uint dwTickCount,
            [In, MarshalAs(UnmanagedType.LPArray)] INTERFACEINFO[]
            lpInterfaceInfo);

        [PreserveSig, MethodImpl(MethodImplOptions.InternalCall,
            MethodCodeType = MethodCodeType.Runtime)]
        int RetryRejectedCall([In] IntPtr htaskCallee, [In] uint dwTickCount,
            [In] uint dwRejectType);

        [PreserveSig, MethodImpl(MethodImplOptions.InternalCall,
            MethodCodeType = MethodCodeType.Runtime)]
        int MessagePending([In] IntPtr htaskCallee, [In] uint dwTickCount,
            [In] uint dwPendingType);
    }

    public class MessageFilter : IMessageFilter
    {
        #region IMessageFilter Members

        public int HandleInComingCall(
            uint dwCallType, IntPtr htaskCaller, uint dwTickCount,
            INTERFACEINFO[] lpInterfaceInfo)
        {
            return 1;
        }

        public int RetryRejectedCall(
            IntPtr htaskCallee, uint dwTickCount, uint dwRejectType)
        {
            //int retVal = -1;
            //Debug.WriteLine("RetryRejectedCall");
            //if (MessageBox.Show("retry?", "Alert", MessageBoxButtons.YesNo)
            //    == DialogResult.Yes)
            //{
            //    retVal = 1;
            //}
            //return retVal;

            //try again after 1 ms
            return 100;
        }

        public int MessagePending(
            IntPtr htaskCallee, uint dwTickCount, uint dwPendingType)
        {
            Debug.WriteLine("MessagePending");
            return 1;
        }

        #endregion

        [DllImport("ole32.dll")]
        static extern int CoRegisterMessageFilter(
            IMessageFilter lpMessageFilter,
            out IMessageFilter lplpMessageFilter);

        private IMessageFilter oldMessageFilter;

    }
}
